<template>
  <div class="v-edit-table">
    <el-table class="v-table" :data="data">
      <template v-for="_column in props.columns" :key="_column.key">
        <el-table-column
          :prop="_column?.key"
          :label="_column?.label"
          :width="_column?.width"
          v-bind="_column"
        >
          <template v-if="$slots[_column.key]" #default="{ row, $index }">
            <slot
              :name="_column.key"
              :row="row"
              :index="$index"
              :value="getVal(row, _column.key)"
            />
          </template>
          <template v-if="_column.editTable" #default="{ row }">
            <span v-if="!row.isEdit">{{ getVal(row, _column.key) }}</span>
            <div class="required">
              <span
                class="required-red"
                v-if="row.isEdit && _column.renderComponents?.required"
                >*</span
              >
              <component
                :placeholder="
                  _column?.renderComponents?.elAttrs?.placeholder ||
                  _column.label
                "
                :is="_column?.renderComponents?.el"
                v-bind="_column?.renderComponents?.elAttrs"
                v-if="row.isEdit"
                v-model="row[_column.key]"
              />
            </div>
            <span
              class="show-msg"
              v-if="
                row.isEdit &&
                _column.renderComponents?.required &&
                !row[_column.key]
              "
              >{{
                _column.renderComponents?.msg || _column.label + '为必填项'
              }}</span
            >
          </template>
          <template v-if="_column.key === 'editActions'" #default="{ row }">
            <CEA v-if="!row.isEdit" @click="handleEdit(row, true)">编辑</CEA>
            <CEA v-if="row.isEdit" @click="handleEdit(row, false)">保存</CEA>
            <CEA v-if="row.isEdit" @click="cancel(row, false)">取消</CEA>
            <CEA @click="handleDelete(row)" type="danger">删除</CEA>
          </template>
        </el-table-column>
      </template>
    </el-table>
  </div>
</template>

<script setup lang="ts">
import defaultProps, { editTableEmits } from './props'

import { getVal } from '@/utils'

import { useHttpData } from './hooks'
import { ElMessage } from 'element-plus'

const emits = defineEmits(editTableEmits)
const props = defineProps(defaultProps)

const { data } = useHttpData(props, () => {
  emits('update:isReload', false)
})

const handleEdit = (row: Record<string, any>, editKey: boolean) => {
  let value = row
  if (props.handler && typeof props.handler === 'function') {
    value = props.handler(row)
  }
  if (!editKey) {
    const requiredArr = props.columns.filter(
      (i: T) => i.renderComponents && i.renderComponents.required
    )
    const isShowMsg = requiredArr.some((item: T) => !row[item.key])
    if (isShowMsg) {
      return false
    }
    if (props.editHttp && typeof props.editHttp === 'function') {
      props.editHttp(row.id, value).then(() => {
        ElMessage({
          type: 'success',
          message: '操作成功'
        })
        emits('update:isReload', true)
      })
    } else {
      row.isEdit = editKey
    }
  } else {
    row.isEdit = editKey
  }
  emits('editNext', value)
}

const handleDelete = (row: Record<string, T>) => {
  if (row.isEdit) {
    return ElMessage({
      type: 'warning',
      message: '请先保存在进行删除操作'
    })
  }
  if (props.delHttp && typeof props.delHttp === 'function') {
    props.delHttp([row.id]).then(() => {
      ElMessage({
        type: 'success',
        message: '删除成功'
      })
      emits('update:isReload', true)
    })
  } else {
    data.value?.splice(data.value?.indexOf(row), 1)
  }
  emits('delNext', row)
}

const cancel = (row: T, editKey: boolean) => {
  const isHttp = props.http && typeof props.http === 'function'
  if (isHttp) {
    emits('update:isReload', true)
  } else {
    emits('reload')
    row.isEdit = editKey
  }
}

defineOptions({
  name: 'VEditTable'
})
</script>

<style lang="scss" scoped>
.required {
  display: flex;
  align-items: center;

  &-red {
    padding-right: 10px;
    color: #ff0000;
  }
}

.show-msg {
  font-size: 12px;
  color: #ff0000;
  padding-left: 20px;
  transition: all 0.6s;
}
</style>
